package com.weipu.common.facade.support.service;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Stack;
import java.util.Timer;
import java.util.Vector;

import android.app.Service;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.IBinder;

import com.weipu.common.facade.support.service.callback.TaskDataBroadcastReceiver;
import com.weipu.common.facade.support.service.task.BaseServiceTask;
import com.weipu.common.facade.support.service.task.GetCacheConfigTask;
import com.weipu.common.util.Logger;
import com.weipu.common.util.ThreadUtil;

@SuppressWarnings("rawtypes")
public class TaskService extends Service
{
    private static final String TAG = "TaskService";
    
    private Vector<BaseServiceTask> taskHistory;//任务历史记录，管理历史任务
    
    private Stack<BaseServiceTask> taskStack;//任务栈
    
    private Timer taskExecutor;//Timer 任务执行者
    
    private static final long CACHE_CONFIG_UPDATE_PEROID = 20 * 60 * 1000;//缓存配置更新周期(非自动更新任务)，该时间为相对于服务onStart出发的时间间隔，所以不一定是每{CacheUpdatePeroid}执行一次
    
    private long cacheConfigUpdateStamp = 0;//缓存配置更新时间戳
    
    //更新缓存配置
    private void updateCacheCfg()
    {
        //启动缓存配置更新任务
        if ((System.currentTimeMillis() - cacheConfigUpdateStamp) >= CACHE_CONFIG_UPDATE_PEROID)
        {
            //更新缓存时间戳
            cacheConfigUpdateStamp = System.currentTimeMillis();
            pushTask(new GetCacheConfigTask());
        }
    }
    
    @Override
    public void onCreate()
    {
        if (Logger.isLog)
        {
            Logger.d(TAG, "onCreate() - start, sevice create.");
        }
        
        super.onCreate();
        
        //注册广播
        IntentFilter filter = new IntentFilter();  
        filter.addAction(TaskDataBroadcastReceiver.ACTION_URL);  
        filter.setPriority(Integer.MAX_VALUE);  
        registerReceiver(myBR, filter); 
        
        taskHistory = new Vector<BaseServiceTask>(); //初始化历史容器对象
        taskStack = new Stack<BaseServiceTask>();//初始化任务栈
        taskExecutor = new Timer("Timer-task-servie", true);//Timer随程序启动销毁
        
        //更新配置缓存
        //更新缓存时间戳
        cacheConfigUpdateStamp = System.currentTimeMillis();
        GetCacheConfigTask task = new GetCacheConfigTask();
        task.setDelay(5 * 60 * 1000);//延迟5分钟加载
        pushTask(task);
    }
    private TaskDataBroadcastReceiver<Integer> myBR = new TaskDataBroadcastReceiver<Integer>() {
		
		@Override
		public void onReceiveData(Integer receiver) {
			// TODO 
			
		}
	};
    @Override
    public void onStart(Intent intent, int startId)
    {
        if (Logger.isLog)
        {
            Logger.d(TAG, "onStart(Intent, int) - start");
        }
        
        super.onStart(intent, startId);
        
        //清理过期的任务记录
        clearTask();
        
        //如果必要则更新缓存
        updateCacheCfg();
        
        //如果添加的任务已经存在(未执行完成则不会重复执行)
        boolean isAddTaskSuccess = false;
        try
        {
            isAddTaskSuccess = addTask2stack(intent);
        }
        catch (Exception e)
        {
            Logger.e(TAG, "addTask2stack error.", e);
        }
        
        //执行任务
        if (isAddTaskSuccess)
        {
            try
            {
                doTask();
            }
            catch (Exception e)
            {
                Logger.e(TAG, "doTask error.", e);
            }
        }
        
        if (Logger.isLog)
        {
            Logger.d(TAG, "onStart(Intent, int) - end");
        }
    }
    

	private void clearTask()
    {
        if (Logger.isLog)
        {
            Logger.d(TAG, "clearTask() - start");
        }
        
        if (null == taskHistory || taskHistory.isEmpty())
        {
            if (Logger.isLog)
            {
                Logger.d(TAG, "clearTask() - end, taskHistory is empty.");
            }
            return;
        }
        
        @SuppressWarnings("unused")
        BaseServiceTask tmpTask = null;//销毁资源
        
        if (Logger.isLog)
        {
            Logger.i(TAG, "clearTask() - begin, task.size: " + (taskHistory.size()));
        }
        
        for (int i = 0; i < taskHistory.size(); i++)
        {
            //任务执行完毕移除任务
            if (taskHistory.get(i).isTaskDone())
            {
                tmpTask = taskHistory.remove(i);
                tmpTask = null;
                i--;
            }
        }
        
        if (Logger.isLog)
        {
            Logger.d(TAG, "clearTask() - end, task.size: " + (taskHistory.size()));
        }
    }
    
    //添加任务列表
    private boolean addTask2stack(Intent intent)
    {
        if (Logger.isLog)
        {
            Logger.d(TAG, "addTask2stack(Intent) - start");
        }
        
        if (null == intent)
        {
            if (Logger.isLog)
            {
                Logger.d(TAG, "addTask2stack(Intent) - end, Intent is null.");
            }
            return false;
        }
        
        Serializable tmpTask = intent.getSerializableExtra(BaseServiceTask.TASK_DATA);
        
        if (Logger.isLog)
        {
            Logger.i(TAG, "addTask2stack(Intent) - taskHistory: " + (null == taskHistory ? "null" : taskHistory.size()));
        }
        
        boolean isAddSuccess = false;
        //添加任务到栈，为防止重复操作，刚刚加入的任务和
        if (tmpTask instanceof BaseServiceTask)
        {
            isAddSuccess = pushTask((BaseServiceTask)tmpTask);
        }
        //执行批量任务处理
        else if (tmpTask instanceof ArrayList)
        {
            ArrayList taskList = (ArrayList)tmpTask;
            
            //检验数据类型格式是否正确
            if (taskList.size() != 0 && taskList.get(0) instanceof BaseServiceTask)
            {
                for (int i = 0; i < taskList.size(); i++)
                {
                    pushTask((BaseServiceTask)taskList.get(i));
                }
                isAddSuccess = true;//添加任务成功
            }
        }
        else
        {
            if (Logger.isLog)
            {
                Logger.i(TAG, "addTask2stack(Intent) - task is not a BaseServiceTask.");
            }
        }
        
        if (Logger.isLog)
        {
            Logger.d(TAG, "addTask2stack(Intent) - end.");
        }
        return isAddSuccess;
    }
    
    private boolean pushTask(BaseServiceTask task)
    {
        if (Logger.isLog)
        {
            Logger.d(TAG, "pushTask - start, task: " + task.getClass());
        }
        
        //任务存在(依据Object.equals)，则不重复添加 
        if (!taskHistory.contains(task))
        {
            taskHistory.add((BaseServiceTask)task);//进入历史记录
            taskStack.push((BaseServiceTask)task);//进入任务栈
            
            if (Logger.isLog)
            {
                Logger.d(TAG, "pushTask - end, Push task to stack.");
            }
            return true;
        }
        
        if (Logger.isLog)
        {
            Logger.d(TAG, "pushTask - end, Push task to fail, Duplicate task.");
        }
        return false;
    }
    
    //正在执行任务
    private void doTask()
    {
        if (Logger.isLog)
        {
            Logger.d(TAG, "doTask() - start");
        }
        
        if (taskStack.isEmpty())
        {
            if (Logger.isLog)
            {
                Logger.d(TAG, "doTask() - end, task stack is empty.");
            }
            return;
        }
        
        if (Logger.isLog)
        {
            Logger.d(TAG, "doTask() - begin, task.size: " + taskStack.size());
        }
        
        int baseTaskDelay = 0;//任务延迟加载，防止当前高并发请求
        
        int currentTaskSize = taskStack.size() + taskHistory.size();//当前任务数: 正在执行和即将执行的
        
        int diff = (currentTaskSize) - ThreadUtil.getInstance().getSupportMaxPoolSize();//任务与线程池之差
        
        //有线程池大小限制，如果任务数量超过线程池最大值则任务梯形延迟加载
        if (ThreadUtil.getInstance().getSupportMaxPoolSize() > 0 && diff > 0)
        {
            baseTaskDelay = diff * 100;
        }
        
        BaseServiceTask tmpTask = null;
        do
        {
            tmpTask = taskStack.pop();
            
            //任务执行方式替换，扩展立即执行机制
            //            //任务队列执行
            //            if (tmpTask.getDelay() > 0)
            //            {
            //                //                taskExecutor.schedule(tmpTask, tmpTask.getDelay());
            //                execute(tmpTask, tmpTask.getDelay());
            //            }
            //            //立即执行
            //            else if (-1 == tmpTask.getDelay())
            //            {
            //                execute(tmpTask, tmpTask.getDelay());
            //            }
            
            //默认队列方式执行
            if (0 == tmpTask.getDelay())
            {
                //                    taskExecutor.schedule(tmpTask, baseTaskDelay);
                execute(tmpTask, baseTaskDelay);
                
                if (baseTaskDelay > 0)
                {
                    baseTaskDelay -= 100; //任务递减延迟加载
                }
            }
            //根据设置值立即执行或按指定延时执行任务
            else
            {
                execute(tmpTask, tmpTask.getDelay());
            }
            
        } while (!taskStack.isEmpty());
        
        if (Logger.isLog)
        {
            Logger.d(TAG, "doTask() - end, taskDelay: " + baseTaskDelay);
        }
    }
    
    //执行任务: 当delay小于0时立即执行，否则队列执行
    private void execute(BaseServiceTask task, long delay)
    {
        //延时小于0则立即执行
        if (delay < 0)
        {
            ThreadUtil.getInstance().getThreadPoolIntance().execute(task);
        }
        //队列执行
        else
        {
            taskExecutor.schedule(task, delay);
        }
    }
    
    @Override
    public IBinder onBind(Intent intent)
    {
        return null;
    }
    
    @Override
    public void onDestroy()
    {
        if (Logger.isLog)
        {
            Logger.d(TAG, "Service onDestroy().");
        }
        unregisterReceiver(myBR);
        super.onDestroy();
    }
    
}
